// License: http://www.codeplex.com/entlibcontrib/Project/License.aspx
// Author: Randy

using System;
using System.Globalization;
using Microsoft.Practices.EnterpriseLibrary.Common.Configuration;
using Microsoft.Practices.EnterpriseLibrary.Common.Configuration.ObjectBuilder;
using Microsoft.Practices.EnterpriseLibrary.Logging;
using Microsoft.Practices.EnterpriseLibrary.Logging.Configuration;
using Microsoft.Practices.EnterpriseLibrary.Logging.Filters;
using Microsoft.Practices.EnterpriseLibrary.Logging.Instrumentation;
using EntLibContrib.Logging.Parser;

using System.Diagnostics;
#if !NUNIT
using Microsoft.VisualStudio.TestTools.UnitTesting;
#else
using NUnit.Framework;
using TestClass = NUnit.Framework.TestFixtureAttribute;
using TestInitialize = NUnit.Framework.SetUpAttribute;
using TestCleanup = NUnit.Framework.TearDownAttribute;
using TestMethod = NUnit.Framework.TestAttribute;
#endif

namespace EntLibContrib.Logging.UnitTests.Parser
{
    [TestClass]
    public class TimeStampFunctionLogFileReaderTests
    {
        private const string configurationFilepath = @"Parser\TimeStampFunctionLogFileReaderTests.config";
        private static int entryLoop = 5000;
        private static bool writeConsole = false;

        [TestMethod]
        public void TestTimeStampFunctionLogFileReader()
        {
            if (Debugger.IsAttached)
                entryLoop = 5;
            if (writeConsole && !Debugger.IsAttached)
            {
                Console.WriteLine();  // new line after dots from NUnit
            }
            foreach (string categoryName in CategoryLogFileReader.ConfigCatagoryNames(configurationFilepath))
            {
                TestTimeStampFunctionLogFileReader(categoryName);
            }
            //TestTimeStampFunctionLogFileReader("FractionTimeStamp");
            //TestTimeStampFunctionLogFileReader("FormatTimeStamp");
            //TestTimeStampFunctionLogFileReader("DefaultTimeStamp");
            #if DEBUG
            if (writeConsole && !Debugger.IsAttached)
            {
                Console.Write("Press any key to continue");
                System.Console.ReadKey();
            }
            #endif
        }
        private static void TestTimeStampFunctionLogFileReader(string categoryName)
        {
            DeleteOldLogFile(categoryName);
            LogWriterFactory logWriterFactory =
                new LogWriterFactory(
                new FileConfigurationSource(configurationFilepath));
            LogWriter writer = logWriterFactory.Create();
            LogEntry writeLogEntry = new LogEntry();
            writeLogEntry.Categories.Add(categoryName);

            int countAddMinutes = 0;  // compensate for round-off in the log file
            writeLogEntry.Message = "Testing first message";
            writeLogEntry.Severity = System.Diagnostics.TraceEventType.Information;
            writeLogEntry.TimeStamp = writeLogEntry.TimeStamp.AddMinutes(countAddMinutes++);
            for (int i = 0; i < entryLoop; i++)
                writer.Write(writeLogEntry);
            CallTimeStampFunctionLogFileReader(categoryName, null, writeLogEntry);

            Filter filter = new Filter();
            filter.StartTime = DateTime.UtcNow.AddMinutes(countAddMinutes++);

            writeLogEntry.Message = "Testing second message";
            writeLogEntry.Severity = System.Diagnostics.TraceEventType.Warning;
            writeLogEntry.TimeStamp = writeLogEntry.TimeStamp.AddMinutes(countAddMinutes++);
            for (int i = 0; i < entryLoop; i++)
                writer.Write(writeLogEntry);

            filter.StopTime = DateTime.UtcNow.AddMinutes(countAddMinutes++);
            TimeTimeStampFunctionLogFileReader(categoryName, filter, writeLogEntry);
        }
        private static void DeleteOldLogFile(string categoryName)
        {
            string logFileName = TimeStampFunctionLogFileReader.GetConfigTraceListenerFileName(configurationFilepath, categoryName);
            if (System.IO.File.Exists(logFileName))
                System.IO.File.Delete(logFileName);
        }
        private static void CallTimeStampFunctionLogFileReader(string categoryName, Filter filter, LogEntry writeLogEntry)
        {
            TimeStampFunctionLogFileReader o = new TimeStampFunctionLogFileReader(configurationFilepath, categoryName, null);
            int entryCount = 0;
            foreach (LogEntry readLogEntry in o.ParseLogFile(null, filter))
            {
                if (readLogEntry.TimeStamp.Hour != writeLogEntry.TimeStamp.Hour)
                Assert.AreEqual(readLogEntry.Message, writeLogEntry.Message);
                Assert.AreEqual(readLogEntry.Severity, writeLogEntry.Severity);
                entryCount++;
            }
            if (entryCount != entryLoop)
                Assert.Fail("Incorrect number of log entries");
        }
        private static void TimeTimeStampFunctionLogFileReader(string categoryName, Filter filter, LogEntry writeLogEntry)
        {
            Stopwatch watch = Stopwatch.StartNew();
            CallTimeStampFunctionLogFileReader(categoryName, filter, writeLogEntry);
            watch.Stop();
            if (writeConsole && !Debugger.IsAttached)
            {
                Console.WriteLine(categoryName +
                    " elapsed seconds = " +
                    watch.ElapsedMilliseconds / 1000.0f);
            }
        }
    }
}
